#ifndef __STDSC_H
#define __STDSC_H

/* Definitions */
#define SCU_BUF_BLOCK_ALL 1

#define SC_VAR_STREAM    0
#define SC_VAR_INTEGER   1
#define SC_VAR_DOUBLE    2
#define SC_VAR_POINTER   3

#define ARG_STREAM_IN            0
#define ARG_STREAM_OUT           1
#define ARG_SCALAR_IN            2
#define ARG_SCALAR_OUT           3
#define ARG_LOOKUP               4

/* Types */
typedef int scu_buf_t;
typedef int scu_bufptrid_t;
typedef int ilp_op_t;

typedef struct tokeninfo_s
{
  int initial, final;
  int request;
} tokeninfo_t;

typedef struct extents_s
{
  int start, end, size, discard, delay;
} extents_t; 

typedef struct data_s
{
  int d;
  double f;
} data_t;

typedef struct arg_state_s
{
  int buffer, delay, state;
} arg_state_t;

typedef struct arg_connector_s
{
  int instance, argument;
} arg_connector_t;

typedef struct ilp_arg_s
{
  data_t data;
  scu_buf_t *buffer;
  scu_bufptrid_t reader;
} ilp_arg_t;

typedef struct bufcode_s
{
  code data, rp, wp;
  int size;
} bufcode_t;

typedef struct argcode_s
{
  code id, argid;
  int argtype;
  code datatype;
  extents_t extents[2];
  int read;

  arg_state_t state;
  arg_connector_t connector;
  int originstate[];
  
  bufcode_t buffer;
  tokeninfo_t tokens;
} argcode_t;

typedef struct instance_s
{
  code skeleton;
  code body;
  code kernel;

  argcode_t argcode[];
  int arguments;
  int runs;
} instance_t;

typedef struct log_default_streams_s
{
  int crit;   
  int err;    
  int warning;
  int notice; 
  int info;   
  int debug;  
  int crawl;  
} log_default_streams_t;

log_default_streams_t ilpl;
ilp_op_t op;              
        
/* Forward function declarations */
int  scuBufferPeek(scu_buf_t *buf, scu_bufptrid_t r, void **data, int size, int options);
void scuBufferReleasePeeked(scu_buf_t *buf, scu_bufptrid_t r, int size);                  
int  scuBufferAllocate(scu_buf_t *buf, void **data, int size, int options);
void scuBufferReleaseAllocated(scu_buf_t *buf, int size);
int  scuBufferRemoveReference(scu_buf_t *buf);
int  scuBufferFinalize(scu_buf_t *buf);
int  scuBufferGetStride(scu_buf_t *buf);
int  scuBufferGetLines(scu_buf_t *buf);
int  scuBufferRead(scu_buf_t *buf, int reader, void *data, int size, int options);
int  scuBufferWrite(scu_buf_t *buf, void *data, int size, int options);

void *malloc(int bytes);
void free(void *a);
void memcpy(void *a, void *b, int size);
void assert(int x);
void memset(void *a, int b, int c);
int printf(char *a);

int BufferGetStride(int arg);
int BufferGetLines(int arg);
int BufferPeek(int arg, void **data, int size, int options);
void BufferReleasePeeked(int arg, int size);
int BufferAllocate(int arg, void **data, int size, int options);
void BufferReleaseAllocated(int arg, int size);
int BufferRemoveReference(int arg);
int BufferFinalize(int arg);

int MIN(int a, int b)
{
  if (a < b) return a;
  else return b;
}

int MAX(int a, int b)
{
  if (a > b) return a;
  else return b;
}

#endif /* __STDSC_H */
